library(leaflet)
library(tidyverse)
library(readxl)
library(lubridate)
library(kableExtra)
library(GGally)
library(corrplot)
library(ggplot2)
library(dplyr)
library(gridExtra)
library(osmdata)
library(sf)
library(ggmap)
library(MASS)Iflow
Librerías
Cargar Datos
df <- read_excel("iFlowDatos.xlsx")
df# A tibble: 27,484 × 16
iddomicilioorden direccion localidad InicioHorario1 FinHorario1 latitud
<dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
2 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
3 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
4 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
5 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
6 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
7 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
8 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
9 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
10 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
# ℹ 27,474 more rows
# ℹ 10 more variables: longitud <dbl>, cliente <dbl>, mes <dbl>, Bultos <dbl>,
# Peso <dbl>, Unidades <dbl>, InicioVisitaPlanificado <chr>,
# FinVisitaPlanificado <chr>, InicioVisitaReal <chr>, FinVisitaReal <chr>
Limpieza de los Datos
df_clean <- df %>%
filter(latitud<(-34),longitud<(-58)) %>%
mutate(inicio = parse_date_time(InicioVisitaReal, orders = c("ymd HMS", "ymd_HMS", "dmy HMS"), tz = Sys.timezone(), quiet = TRUE)) %>% na.omit()%>%
mutate(cliente = as.factor(cliente))
names(df_clean) <- tolower(names(df_clean))
df_clean# A tibble: 27,382 × 17
iddomicilioorden direccion localidad iniciohorario1 finhorario1 latitud
<dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
2 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
3 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
4 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
5 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
6 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
7 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
8 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
9 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
10 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
# ℹ 27,372 more rows
# ℹ 11 more variables: longitud <dbl>, cliente <fct>, mes <dbl>, bultos <dbl>,
# peso <dbl>, unidades <dbl>, iniciovisitaplanificado <chr>,
# finvisitaplanificado <chr>, iniciovisitareal <chr>, finvisitareal <chr>,
# inicio <dttm>
dim(df_clean)[1] 27382 17
Análisis de Datos Básico
summary(df_clean) iddomicilioorden direccion localidad iniciohorario1
Min. : 74956 Length:27382 Length:27382 Min. : 0
1st Qu.: 77460 Class :character Class :character 1st Qu.:901
Median : 82348 Mode :character Mode :character Median :901
Mean :101622 Mean :901
3rd Qu.:121664 3rd Qu.:901
Max. :183277 Max. :901
finhorario1 latitud longitud cliente mes
Min. :1400 Min. :-34.85 Min. :-58.73 20:16510 Min. :5.000
1st Qu.:1401 1st Qu.:-34.62 1st Qu.:-58.48 70:10872 1st Qu.:5.000
Median :1401 Median :-34.60 Median :-58.44 Median :6.000
Mean :1401 Mean :-34.60 Mean :-58.44 Mean :6.021
3rd Qu.:1401 3rd Qu.:-34.58 3rd Qu.:-58.40 3rd Qu.:7.000
Max. :2359 Max. :-34.39 Max. :-58.15 Max. :7.000
bultos peso unidades iniciovisitaplanificado
Min. : 0.100 Min. : 0.00 Min. : 1.00 Length:27382
1st Qu.: 2.000 1st Qu.: 13.00 1st Qu.: 2.00 Class :character
Median : 3.000 Median : 20.94 Median : 6.00 Mode :character
Mean : 5.692 Mean : 40.95 Mean : 28.37
3rd Qu.: 6.000 3rd Qu.: 39.00 3rd Qu.: 40.00
Max. :360.000 Max. :2475.00 Max. :2203.00
finvisitaplanificado iniciovisitareal finvisitareal
Length:27382 Length:27382 Length:27382
Class :character Class :character Class :character
Mode :character Mode :character Mode :character
inicio
Min. :2024-05-03 07:17:51.00
1st Qu.:2024-05-24 15:38:00.00
Median :2024-06-18 10:34:53.00
Mean :2024-06-17 22:15:43.75
3rd Qu.:2024-07-11 11:21:32.00
Max. :2024-08-06 16:57:00.00
Distintas Variables
colnames(df_clean) [1] "iddomicilioorden" "direccion"
[3] "localidad" "iniciohorario1"
[5] "finhorario1" "latitud"
[7] "longitud" "cliente"
[9] "mes" "bultos"
[11] "peso" "unidades"
[13] "iniciovisitaplanificado" "finvisitaplanificado"
[15] "iniciovisitareal" "finvisitareal"
[17] "inicio"
sapply(df_clean, class)$iddomicilioorden
[1] "numeric"
$direccion
[1] "character"
$localidad
[1] "character"
$iniciohorario1
[1] "numeric"
$finhorario1
[1] "numeric"
$latitud
[1] "numeric"
$longitud
[1] "numeric"
$cliente
[1] "factor"
$mes
[1] "numeric"
$bultos
[1] "numeric"
$peso
[1] "numeric"
$unidades
[1] "numeric"
$iniciovisitaplanificado
[1] "character"
$finvisitaplanificado
[1] "character"
$iniciovisitareal
[1] "character"
$finvisitareal
[1] "character"
$inicio
[1] "POSIXct" "POSIXt"
Cambiar las variables, para que las que tengan que estar en formato fecha, lo estén
df_clean$iniciovisitaplanificado <- as.POSIXct(df_clean$iniciovisitaplanificado, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
df_clean$finvisitaplanificado <- as.POSIXct(df_clean$finvisitaplanificado, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
df_clean$iniciovisitareal <- as.POSIXct(df_clean$iniciovisitareal, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
df_clean$finvisitareal <- as.POSIXct(df_clean$finvisitareal, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
df_clean# A tibble: 27,382 × 17
iddomicilioorden direccion localidad iniciohorario1 finhorario1 latitud
<dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
2 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
3 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
4 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
5 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
6 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
7 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
8 74956 VIDAL 2044 CAPITAL 901 1401 -34.6
9 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
10 74958 M PEDRAZA 2370 CAPITAL 901 1401 -34.6
# ℹ 27,372 more rows
# ℹ 11 more variables: longitud <dbl>, cliente <fct>, mes <dbl>, bultos <dbl>,
# peso <dbl>, unidades <dbl>, iniciovisitaplanificado <dttm>,
# finvisitaplanificado <dttm>, iniciovisitareal <dttm>, finvisitareal <dttm>,
# inicio <dttm>
colnames(df_clean) [1] "iddomicilioorden" "direccion"
[3] "localidad" "iniciohorario1"
[5] "finhorario1" "latitud"
[7] "longitud" "cliente"
[9] "mes" "bultos"
[11] "peso" "unidades"
[13] "iniciovisitaplanificado" "finvisitaplanificado"
[15] "iniciovisitareal" "finvisitareal"
[17] "inicio"
sapply(df_clean, class)$iddomicilioorden
[1] "numeric"
$direccion
[1] "character"
$localidad
[1] "character"
$iniciohorario1
[1] "numeric"
$finhorario1
[1] "numeric"
$latitud
[1] "numeric"
$longitud
[1] "numeric"
$cliente
[1] "factor"
$mes
[1] "numeric"
$bultos
[1] "numeric"
$peso
[1] "numeric"
$unidades
[1] "numeric"
$iniciovisitaplanificado
[1] "POSIXct" "POSIXt"
$finvisitaplanificado
[1] "POSIXct" "POSIXt"
$iniciovisitareal
[1] "POSIXct" "POSIXt"
$finvisitareal
[1] "POSIXct" "POSIXt"
$inicio
[1] "POSIXct" "POSIXt"
Análisis
df_clean <- df_clean %>%
mutate(TiempoEntrega = finvisitareal - iniciovisitareal)Cantidad de entregas por localidad
df_counts <- df_clean %>%
group_by(localidad) %>%
summarise(conteo = n())%>%
arrange(desc(conteo))%>%
head(5)
ggplot(df_counts, aes(x = localidad, y =conteo)) +
geom_bar(stat = "identity") 
Este gráfico permite identificar las 5 localidades con mayor carga de entregas y lo hicimos para explorar el dato de localidad. Las localidades con barras más altas son las que tienen un mayor volumen de entregas, lo cual puede ayudar a la empresa a focalizar recursos en estas áreas.
Calculamos el tiempo promedio de demora en la salida, y en la llegada (Los datos de las visitas planificadas están mal cargados, por lo que este análisis no lo pudimos hacer de forma correcta)
calcular_tiempo_formateado <- function(inicio, fin) {
# Calcula la diferencia en minutos con decimales
tiempo_minutos_dec <- as.numeric(difftime(fin, inicio, units = "mins"))
tiempo_minutos <- floor(tiempo_minutos_dec)
# Retorna el valor numérico
return(tiempo_minutos)
}
df_clean <- df_clean %>%
mutate(DemoraSalida = calcular_tiempo_formateado(iniciovisitaplanificado, iniciovisitareal))%>%
mutate(DemoraLlegada = calcular_tiempo_formateado(finvisitaplanificado, finvisitareal))
promedio_demora_salida <- mean(df_clean$DemoraSalida,na.rm = TRUE)
promedio_demora_salida[1] 133.482
promedio_demora_llegada <- mean(df_clean$DemoraLlegada,na.rm=TRUE)
promedio_demora_llegada[1] 139.4571
Calculamos el tiempo promedio de demora en la salida y llegada.
Con lo calculado arriba, sacamos el tiempo promedio de demora en la salida y llegada, en las distintas localidades y graficamos
df_demora_por_localidad <- df_clean%>%
group_by(localidad) %>%
summarise(demora_salida_localidad=mean(DemoraSalida,na.rm = T),demora_llegada_localidad=mean(DemoraLlegada,na.rm = T)) %>%
arrange(demora_salida_localidad) %>%
filter(demora_salida_localidad < 3000) %>%
mutate(localidad = factor(localidad, levels = localidad))
ggplot(df_demora_por_localidad,aes(x=localidad,y=demora_salida_localidad)) +
geom_bar(stat="identity") +
labs(title = "Demora de Salida por Localidad",
x = "Localidad",
y = "Demora de Salida (promedio)") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(df_demora_por_localidad,aes(x=localidad,y=demora_llegada_localidad))+
geom_bar(stat="identity")+
labs(title = "Demora de llegada por Localidad",
x = "Localidad",
y = "Demora de Llegada (promedio)") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Ahora calculamos la demora promedio por cliente
demora_promedio_por_cliente <- df_clean%>%
group_by(cliente) %>%
summarise(demora_salida_cliente=mean(DemoraSalida,na.rm=T),demora_llegada_cliente=mean(DemoraLlegada,na.rm=T))
demora_melt <- reshape2::melt(demora_promedio_por_cliente, id.vars = 'cliente')
# Crear el gráfico con ggplot2
ggplot(demora_melt, aes(x = factor(cliente), y = value, fill = variable)) +
geom_bar(stat = 'identity', position = 'dodge') +
labs(x = 'Cliente', y = 'Demora', fill = 'Tipo de demora') +
scale_fill_manual(
values = c("demora_salida_cliente" = "#FF6347", "demora_llegada_cliente" = "#20B2AA"),
labels = c("demora_salida_cliente" = "Demora de Salida por Cliente",
"demora_llegada_cliente" = "Demora de Llegada por Cliente")
) +
theme_minimal()
Distribución de las entregas en un mapa
library(dplyr)
library(sf)
library(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:MASS':
select
The following object is masked from 'package:ggmap':
wind
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
Sys.setenv("MAPBOX_TOKEN" = "pk.eyJ1IjoiYWd1c3Rpbm9ydWUiLCJhIjoiY20yamR1dmlhMDRnMjJscHgxZTk4a3Z1OSJ9.3XpQh1Kfpitza34209j9vA")
df.sf <- df %>%
filter(!is.na(longitud) & !is.na(latitud)) %>%
filter(longitud < 0) %>%
filter(latitud < -34.0) %>%
st_as_sf(coords = c("longitud", "latitud"), crs = 4326)
coords <- st_coordinates(df.sf)
plot_ly() %>%
add_trace(
type = 'scattermapbox',
mode = 'markers',
lon = coords[, 1],
lat = coords[, 2],
marker = list(size = 8, color = 'blue')
) %>%
layout(
mapbox = list(
style = 'streets',
zoom = 8,
center = list(lon = mean(coords[, 1]), lat = mean(coords[, 2]))
),
showlegend = FALSE
) %>%
config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN")) Concentración de entregas
library(leaflet.extras)
leaflet(df_clean) %>%
addTiles() %>%
addHeatmap(lng = ~longitud, lat = ~latitud, intensity = ~unidades, blur = 25, max = 0.05, radius = 15) %>%
addLegend(position = "bottomright", colors = "red", labels = "Concentración de envíos", title = "Leyenda")Estos mapas muestran dónde se encuentran las entregas en el área de interés, lo cual es útil para identificar zonas con alta o baja concentración de entregas. Puede ayudar a identificar si las entregas están concentradas en ciertas áreas o si están distribuidas uniformemente.
Distribucion de las entregas de los distintos clientes
library(dplyr)
library(sf)
library(plotly)
Sys.setenv("MAPBOX_TOKEN" = "pk.eyJ1IjoiYWd1c3Rpbm9ydWUiLCJhIjoiY20yamR1dmlhMDRnMjJscHgxZTk4a3Z1OSJ9.3XpQh1Kfpitza34209j9vA")
df.sf <- df %>%
filter(!is.na(longitud) & !is.na(latitud)) %>%
filter(longitud < 0) %>%
filter(latitud < -34.0) %>%
st_as_sf(coords = c("longitud", "latitud"), crs = 4326)
# Extraer las coordenadas
coords <- st_coordinates(df.sf)
# Asignar etiquetas para la leyenda
df.sf$label <- case_when(
df.sf$cliente == 20 ~ 'Cliente 20', # Etiqueta para cliente 20
df.sf$cliente == 70 ~ 'Cliente 70', # Etiqueta para cliente 70
TRUE ~ 'Otros Clientes' # Otros clientes
)
# Asignar colores basados en la etiqueta
df.sf$color <- case_when(
df.sf$cliente == 20 ~ '#FF6347',
df.sf$cliente == 70 ~ '#20B2AA',
TRUE ~ 'black'
)
# Crear el gráfico con leyenda y colores personalizados
plot_ly() %>%
add_trace(
type = 'scattermapbox',
mode = 'markers',
lon = coords[, 1],
lat = coords[, 2],
text = df.sf$cliente,
marker = list(
size = 8,
color = df.sf$color
),
showlegend = TRUE,
name = df.sf$label
) %>%
layout(
mapbox = list(
style = 'streets',
zoom = 8,
center = list(lon = mean(coords[, 1]), lat = mean(coords[, 2]))
),
showlegend = TRUE
) %>%
config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN"))Concentración de las entregas de los distintos clientes
library(leaflet)
library(leaflet.extras)
library(dplyr)
library(KernSmooth)KernSmooth 2.23 loaded
Copyright M. P. Wand 1997-2009
library(readxl)
df_clean <- df_clean %>%
mutate(
lat = as.numeric(df_clean$latitud),
lon = as.numeric(df_clean$longitud)
) %>%
filter(!is.na(latitud) & !is.na(longitud)) # Filtrar para eliminar filas con NA
df_cliente_20 <- df_clean %>% filter(cliente == 20)
df_cliente_70 <- df_clean %>% filter(cliente == 70)
# Crear el mapa interactivo
leaflet() %>%
addTiles() %>%
addHeatmap(
data = df_cliente_20,
lng = ~lon, lat = ~lat, intensity = 1,
blur = 28, max = 0.1, radius = 15,
gradient = colorRampPalette(c("transparent", "blue", "yellow", "red"))(256),
group = "Cliente 20"
) %>%
addHeatmap(
data = df_cliente_70,
lng = ~lon, lat = ~lat, intensity = 1,
blur = 20, max = 0.1, radius = 15,
gradient = colorRampPalette(c("transparent", "green", "yellow", "orange"))(256),
group = "Cliente 70"
) %>%
setView(lng = mean(df_clean$longitud, na.rm = TRUE), lat = mean(df_clean$latitud, na.rm = TRUE), zoom = 10) %>%
addLayersControl(
overlayGroups = c("Cliente 20", "Cliente 70"),
options = layersControlOptions(collapsed = FALSE)
) %>%
addLegend(position = "bottomright",
colors = colorRampPalette(c("blue", "yellow", "red"))(3),
labels = c("Baja concentración", "Media concentración", "Alta concentración"),
title = "Densidad Cliente 20") %>%
addLegend(position = "bottomleft",
colors = colorRampPalette(c("green", "yellow", "orange"))(3),
labels = c("Baja concentración", "Media concentración", "Alta concentración"),
title = "Densidad Cliente 70")library(leaflet)
library(leaflet.extras)
library(dplyr)
library(readxl)
df_clean <- df_clean %>%
mutate(
lat = as.numeric(latitud),
lon = as.numeric(longitud)
) %>%
filter(!is.na(lat) & !is.na(lon))
df_cliente_20 <- df_clean %>% filter(cliente == 20)
df_cliente_70 <- df_clean %>% filter(cliente == 70)
leaflet() %>%
addTiles() %>%
# Añadir markers para cliente 20 con clustering
addMarkers(
data = df_cliente_20,
lng = ~lon, lat = ~lat,
clusterOptions = markerClusterOptions(),
group = "Cliente 20"
) %>%
# Añadir markers para cliente 70 con clustering
addMarkers(
data = df_cliente_70,
lng = ~lon, lat = ~lat,
clusterOptions = markerClusterOptions(),
group = "Cliente 70"
) %>%
setView(lng = mean(df_clean$lon, na.rm = TRUE), lat = mean(df_clean$lat, na.rm = TRUE), zoom = 10) %>%
addLayersControl(
overlayGroups = c("Cliente 20", "Cliente 70"),
options = layersControlOptions(collapsed = FALSE)
) Estos mapas muestran la ubicación de las entregas y permite identificar patrones geográficos específicos para los clientes destacados. Esto puede ayudar a entender las aréas en las cuales los clientes están mayormente concentrados.
La diferenciación de clientes a través de colores y etiquetas facilita la visualización y el análisis. En estos gráficos, también se puede seleccionar la opción de visualizar los 2 clientes al mismo tiempo, ó cada uno por separado.
Peso por unidad
peso_por_unidad <- function(peso, unidades) {
if (unidades == 0) {
return(NA)
} else {
return(peso / unidades)
}
}
df$peso_por_unidad <- mapply(peso_por_unidad, df$Peso, df$Unidades)
head(df[c("Peso", "Unidades", "peso_por_unidad")])# A tibble: 6 × 3
Peso Unidades peso_por_unidad
<dbl> <dbl> <dbl>
1 24.9 30 0.830
2 26.3 38 0.691
3 24.9 32 0.778
4 14.0 28 0.501
5 14.4 31 0.464
6 13.8 25 0.551
ggplot(df, aes(x = peso_por_unidad)) +
geom_histogram(binwidth = 0.6, fill = "blue", color = "black") +
labs(title = "Distribución del Peso por Unidad", x = "Peso por Unidad", y = "Frecuencia")
Este gráfico muestra la cantidad de unidades que hay por peso.
Cantidad de entregas por mes
# Cargar librerías necesarias
library(ggplot2)
library(lubridate)
df$InicioVisitaReal <- as.Date(df$InicioVisitaReal, format = "%Y-%m-%d")
df_cantidad_de_entregas_por_dia<-df%>%
group_by(InicioVisitaReal)%>%
summarise(n=n())%>%
mutate(mes = month(InicioVisitaReal))
ggplot(df_cantidad_de_entregas_por_dia, aes(x = InicioVisitaReal, y = n)) +
geom_line(size = 0.8, color="blue") +
geom_point(size = 1.5, color="blue") +
labs(title = "Cantidad de entregas a lo largo del tiempo por mes",
x = "Fecha de Inicio de Visita",
y = "Cantidad de entregas") +
theme_minimal() +
theme(panel.grid.major = element_line(color = "gray90")) Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

El gráfico de líneas muestra cómo varía el número de entregas día a día, lo cual puede ayudar a identificar patrones estacionales. Se puede observar si hay picos en ciertas fechas, lo que podría coincidir con eventos o períodos de alta demanda.
Cantidad de entregas por cliente en todos los meses
df$InicioVisitaPlanificado <- as.Date(df$InicioVisitaPlanificado, format = "%Y-%m-%d")
df$cliente<-as.character(df$cliente)
cantidad_entregas_por_cliente<-df%>%
group_by(InicioVisitaPlanificado,cliente)%>%
summarise(n=n())%>%
mutate(mes = month(InicioVisitaPlanificado))
cantidad_entregas_por_cliente# A tibble: 149 × 4
# Groups: InicioVisitaPlanificado [77]
InicioVisitaPlanificado cliente n mes
<date> <chr> <int> <dbl>
1 2024-05-03 20 192 5
2 2024-05-03 70 159 5
3 2024-05-04 20 212 5
4 2024-05-04 70 141 5
5 2024-05-06 20 175 5
6 2024-05-06 70 141 5
7 2024-05-07 20 292 5
8 2024-05-07 70 184 5
9 2024-05-08 20 321 5
10 2024-05-08 70 164 5
# ℹ 139 more rows
ggplot(cantidad_entregas_por_cliente, aes(x =InicioVisitaPlanificado , y = n, color = cliente)) +
geom_line(size = 1) +
geom_point(size = 2.5) +
labs(title = "Cantidad de productos entregados por cliente cada día",
x = "Fecha de Entrega",
y = "Cantidad de Productos Entregados",
color = "Cliente") +
theme_minimal()
Cada línea representa la tendencia de entregas de un cliente en el tiempo. Esto permite comparar el comportamiento de cada cliente y ver quién tiene más o menos entregas en un periodo determinado.
Distribución de Entregas en las distintas horas del día
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
# Convertir 'InicioVisitaReal' a formato POSIXct
df_clean$iniciovisitareal <- as.POSIXct(df_clean$iniciovisitareal, format = "%Y-%m-%d %H:%M:%S")
# Crear las columnas 'dia' y 'hora' a partir de 'InicioVisitaReal'
df_clean$dia <- format(df_clean$iniciovisitareal, "%Y-%m-%d")
df_clean$hora <- format(df_clean$iniciovisitareal, "%H")
# Agrupar los datos por día y contar el número de entregas por día
entregas_por_dia <- df_clean %>%
group_by(dia) %>%
summarise(cantidad_entregas = n())
# Agrupar los datos por hora y contar el número de entregas por hora
# Convertir 'hora' a numérico para el eje X
df_clean$hora <- as.numeric(df_clean$hora)
entregas_por_hora <- df_clean %>%
group_by(hora) %>%
summarise(cantidad_entregas = n())
# Graficar la cantidad de entregas por hora
ggplot(entregas_por_hora, aes(x = hora, y = cantidad_entregas)) +
geom_bar(stat = "identity", fill = "lightblue", color = "black") +
labs(title = "Cantidad de Entregas por Hora", x = "Hora", y = "Cantidad de Entregas") +
theme_minimal() +
scale_x_continuous(breaks = 0:23) # Asegurarse de que el eje X muestra las horas adecuadamente
Podemos observar la cantidad de entregas en las distintas horas del día, lo que nos puede ayudar a ver en que horarios hay una mayor demanda de entregas.
Distribución de entregas en los distintos días de la semana
library(plotly)
library(dplyr)
library(sf)
library(lubridate)
df$InicioVisitaPlanificado <- as.Date(df$InicioVisitaPlanificado, format = "%Y-%m-%d")
df <- df %>%
mutate(dia_semana = wday(InicioVisitaPlanificado, label = TRUE, abbr = FALSE))
df.sf <- df %>%
filter(!is.na(longitud) & !is.na(latitud)) %>%
filter(longitud < 0) %>%
filter(latitud < -34.0) %>%
st_as_sf(coords = c("longitud", "latitud"), crs = 4326)
coords <- st_coordinates(df.sf)
plot_ly() %>%
add_trace(
type = 'scattermapbox',
mode = 'markers',
lon = coords[, 1],
lat = coords[, 2],
text = ~paste(df.sf$cliente, "<br>", df.sf$dia_semana),
marker = list(
size = 8
),
color = ~df.sf$dia_semana,
colors = 'Set1'
) %>%
layout(
mapbox = list(
style = 'streets',
zoom = 8,
center = list(lon = mean(coords[, 1]), lat = mean(coords[, 2]))
),
showlegend = TRUE
) %>%
config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN"))En este mapa se puede ver la distribución de las entregas en los distintos días de la semana, viendo en que días se repartieron mayores entregas. Se pueden observar los datos de todos los días al mismo tiempo, ó cada día separado al tocar 2 veces en el día deseado.
Cluster de Entregas por Localidad
coords <- df_clean %>%
select(latitud, longitud) %>%
na.omit()
clusters <- kmeans(coords, centers = 3)
df_clean$cluster <- as.factor(clusters$cluster)
ggplot(df_clean, aes(x = longitud, y = latitud, color = cluster)) +
geom_point() +
labs(title = "Clusters de Entregas por Localidad") +
theme_minimal()
Cada color representa un grupo geográfico de entregas, lo que ayuda a identificar áreas con mayor densidad de actividad. Los clusters pueden sugerir la presencia de distintas zonas de entrega con alta demanda o regiones donde las entregas tienden a agruparse.
Distribución de la cantidad de unidades
library(leaflet)
library(leaflet.extras)
leaflet(df_clean) %>%
addTiles() %>%
addHeatmap(lng = ~longitud, lat = ~latitud, intensity = ~unidades, blur = 20, max = 0.05, radius = 15) %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, radius = ~sqrt(unidades),
color = "#0074D9", fillColor = "#0074D9", fillOpacity = 0.5,
popup = ~paste("Cantidad de Unidades:", unidades),
clusterOptions = markerClusterOptions())